package
{
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.PixelSnapping;
	import flash.display.Sprite;
	import flash.events.FocusEvent;
	import flash.events.KeyboardEvent;
	import flash.events.MouseEvent;
	import flash.geom.Rectangle;
	import flash.utils.ByteArray;

	public class Console extends Sprite
	{		
		public static var TvRect:Rectangle;
		public static var TvH:uint, TvY:uint;
		public static var TvRAM:BitmapData;
		private static var TvObj:Bitmap;
		
		public static var TvShadow:ByteArray;
		
		//public static var dbg:Boolean = false;
		
		public function Console(hres:uint, vres:uint) {
			super();
			TvRect = new Rectangle(0,0,TvH,TvY);
			TvH = hres;
			TvY = vres;
			TvRAM = new BitmapData(TvH, TvY, false, 0xFFFFFF);
			TvObj = new Bitmap(TvRAM, PixelSnapping.ALWAYS, false);
			/****/
			TvShadow = new ByteArray();			
			//for (var i:uint = 0; i<(TvH*TvY*4); i++) TvShadow[i]=0xFF;
			VideoFetch();
			/****/
			addChild(TvObj);
			m1.debug.print("Tv Initialized.");
			/******* Focus Event Handlers *******/
			addEventListener(FocusEvent.FOCUS_IN, function(ev:FocusEvent):void{IRQ.Assert(IRQ.FocusIRQ, IRQ.FocIn, 0, 0)});
			addEventListener(FocusEvent.FOCUS_OUT, function(ev:FocusEvent):void{IRQ.Assert(IRQ.FocusIRQ, IRQ.FocOut, 0, 0)});
			/******* Mouse Event Handlers *******/
			addEventListener(MouseEvent.MOUSE_DOWN, function(ev:MouseEvent):void{
				GrabFocus(); /* Always force keyboard focus into console window on mouse click */
				IRQ.Assert(IRQ.MouseIRQ, IRQ.MouseDown, ev.localX, ev.localY);
			});
			addEventListener(MouseEvent.MOUSE_UP, function(ev:MouseEvent):void{IRQ.Assert(IRQ.MouseIRQ, IRQ.MouseUp, ev.localX, ev.localY)});
			addEventListener(MouseEvent.MOUSE_MOVE, function(ev:MouseEvent):void{IRQ.Assert(IRQ.MouseIRQ, IRQ.MouseMove, ev.localX, ev.localY)});
			addEventListener(MouseEvent.MOUSE_OUT, function(ev:MouseEvent):void{IRQ.Assert(IRQ.MouseIRQ, IRQ.MouseOut, ev.localX, ev.localY)});
			addEventListener(MouseEvent.MOUSE_OVER, function(ev:MouseEvent):void{IRQ.Assert(IRQ.MouseIRQ, IRQ.MouseOver, ev.localX, ev.localY)});
			addEventListener(MouseEvent.MOUSE_WHEEL, function(ev:MouseEvent):void{IRQ.Assert(IRQ.MouseIRQ, IRQ.MouseWheel, ev.localX, ev.localY)});
			/******* Keyboard Event Handlers *******/
			addEventListener(KeyboardEvent.KEY_DOWN, function(ev:KeyboardEvent):void{IRQ.Assert(IRQ.KbdIRQ, IRQ.KbdMake, ev.keyCode, ev.keyLocation)});
			addEventListener(KeyboardEvent.KEY_UP, function(ev:KeyboardEvent):void{IRQ.Assert(IRQ.KbdIRQ, IRQ.KbdBreak, ev.keyCode, ev.keyLocation)});
			/***************************************/
			m1.debug.print("Console I/O Initialized.");
		}
		
		/* Grab console focus */
		private function GrabFocus():void {
			stage.focus = this;
		}

		/******* Video Routines *******/
		
		public function VideoRAMSize():uint {
			return TvH*TvY*4;
		}
		
		public static function VideoSync():void {
			debug("vsync...");
			TvRAM.setPixels(TvRect, TvShadow);
			debug("vsync ok");
		}

		public static function VideoFetch():void {
			debug("vfetch...");
			TvShadow.position = 0;
			TvShadow.writeBytes(TvRAM.getPixels(TvRect));
			debug("vfetch ok");
		}
		
		/* ... */
		
        private static function debug(msg:String):void {
        	m1.debug.print("CONSOLE: " + msg);
        }
	}
}